---
title: Configuration
summary: Environment API settings, the Web.config surface, embedded constants, and per-variant transforms.
status: draft
owner: Not determined from source
last_reviewed: 2026-09-22
---

# Configuration

`clsADUserServices` holds no runtime configuration of its own in `Web.config` — `<appSettings/>` and `<connectionStrings/>` are both present but empty, self-closing elements. The service's entire configurable surface is a single setting, `aduserservices.allowedips`, retrieved at request time from the SAIF environment service. Everything else that varies per environment in this repository — the directory domains and containers the service targets — is compiled into the assembly as `Const` declarations and cannot change without a rebuild.

## Configuration model

| Aspect | Finding |
| --- | --- |
| Primary mechanism | Environment API (`WebEnvironmentService`) |
| Read through | `New WebEnvironmentService("aduserservices").GetConfigSetting("aduserservices.allowedips")` |
| Read timing | Per request — a new `WebEnvironmentService` instance is constructed and the setting re-fetched on every call to `GetAllowedIPs`, which is reached only from `CheckAccess` |
| `<connectionStrings>` element | Present but empty (self-closing, no `<add>` child) |
| Transform files | `Web.Debug.config` (no-op — commented examples only), `Web.Release.config` (`RemoveAttributes(debug)` only) |

A reader should understand that this service has no `appSettings`, no connection strings, no custom configuration sections, and no typed `ApplicationSettingsBase` settings — every one of those mechanisms was checked and found empty or absent. The one configuration value the service reads arrives from the SAIF environment service on every gated request, not from a file deployed with the application. Separately, four AD domain/container values and one dead LDAP-prefix value are compiled into the assembly as constants; they look like configuration to a reader searching `Web.config`, but they are not there and cannot be changed without a rebuild.

## Environment API settings

| Key | Retrieved by | Consuming class | Secure | Varies by environment | Purpose |
| --- | --- | --- | --- | --- | --- |
| `aduserservices.allowedips` | `GetConfigSetting` | `clsADUserServices.GetAllowedIPs` (`src\ADUserServices\clsADUserServices.asmx.vb:791-796`) | No | Yes | Comma-separated network-origin allow-list evaluated by `CheckAccess` to gate the eight mutating/password operations |

The manifest declares this setting under group `AdUserServices` and key `allowedips` (`environmentsettings\settings.yml`), while the code composes and requests the literal key `aduserservices.allowedips` from a `WebEnvironmentService` constructed with the literal application name `"aduserservices"` (all lower case). The composition and case-folding rules that reconcile these two forms are implemented inside `SAIF.Framework.dll` and are not visible in this repository, so whether the mismatch is benign is unconfirmed.**

| Aspect | Finding |
| --- | --- |
| Environment service application name | `"aduserservices"` |
| Construction | Per request — a new `WebEnvironmentService` instance is constructed inside `GetAllowedIPs` on every call |
| Caching | Not cached — the setting is re-fetched from the environment service on every gated request, making each mutating call dependent on environment-service availability and latency* |
| Failure behavior | No null/empty guard exists before `.Split(",")` is called on the returned value; a missing or unreachable setting propagates as an unhandled exception (framework SOAP fault) instead of the `AccessDenied` sentinel — see [Faults and error pipeline](faults.md) and [Tech debt](tech-debt.md) (TD-12, MEDIUM) |

## Configuration reads

| Setting | Key | Source | Read by | Timing | Purpose |
| --- | --- | --- | --- | --- | --- |
| Allowed IPs | `aduserservices.allowedips` | Environment API | `clsADUserServices.GetAllowedIPs` (lines 791–796), reached only from `clsADUserServices.CheckAccess` (lines 752–776) | Per request | Comma-separated network-origin allow-list evaluated by `CheckAccess` to gate the eight mutating/password operations |

No `WebConfigurationManager.OpenWebConfiguration` call is present in this codebase; configuration is read via `WebEnvironmentService.GetConfigSetting`, not `WebConfigurationManager`. `ConfigurationManager.AppSettings`, a custom `<configSections>` handler, and any `ApplicationSettingsBase` typed setting are likewise absent — each was checked and confirmed absent by direct read.

## Embedded constants

| Constant | Value | Declared in | Purpose | Changeable without a rebuild |
| --- | --- | --- | --- | --- |
| `DOMAIN_EXT` | `external.saif.com` | `clsADUserServices.asmx.vb` lines 45–48 | External customer/policyholder domain; target of every mutating operation and the default for reads when `inExternalDomain` is `True` | No |
| `DOMAIN_INT` | `corp.saif.com` | `clsADUserServices.asmx.vb` lines 45–48 | Internal workforce domain; reachable by reads when `inExternalDomain` is `False`; hard-wired for `GetUserPrinter` | No |
| `CONTAINER_EXT` | `DC=external,DC=saif,DC=com` | `clsADUserServices.asmx.vb` lines 45–48 | Base container for new-account creation, composed as `CN=Users,` + this constant | No |
| `CONTAINER_INT` | `DC=corp,DC=saif,DC=com` | `clsADUserServices.asmx.vb` lines 45–48 | Declared but never passed to `GetContext`; internal-domain contexts are always built unscoped (dead) | No |
| `LDAP` | `LDAP://` | `clsADUserServices.asmx.vb` line 49 | Declared, never referenced (dead) | No |

## Web.config settings

### appSettings

No entries — `<appSettings/>` is declared as an empty, self-closing element in `src\ADUserServices\Web.config`; no key is read from it anywhere in source.

### connectionStrings

No entries — `<connectionStrings/>` is declared as an empty, self-closing element. No connection string, provider, or credential is defined anywhere in the repository. The service performs no database access at all; its only backing store is Active Directory, documented under [Dependencies](dependencies.md).

### system.web

| Element | Setting | Purpose |
| --- | --- | --- |
| `<compilation>` | `targetFramework="4.6.2"`, `debug="true"`, `strict="false"`, `explicit="true"` | Target framework and debug compilation. `debug="true"` is checked in (see [Tech debt](tech-debt.md) TD-13, MEDIUM) and is removed only by the `Release` transform |
| `<authentication>` | `mode="Windows"` | Declares Windows authentication; see [Authentication and authorization](authentication-authorization.md) for why it is not the effective gate |
| `<customErrors>` | Not declared — present only as a commented-out example block | Framework default applies; see [Faults and error pipeline](faults.md) |
| `<webServices><protocols>` | Not declared | Which binding (SOAP 1.1, SOAP 1.2, or the ASMX built-in test-form protocol) is published is at framework defaults; not evidenced by any repository artifact** |

### system.webServer

No `<system.webServer>` section appears in `Web.config`.

### Custom configuration sections

None — no `<configSections>` element is declared anywhere in `Web.config`.

### Assembly binding redirects

None found.

## Configuration transforms

| Transform file | Build configuration | Deployment variant | Changes applied |
| --- | --- | --- | --- |
| `Web.Debug.config` | `Debug` | Local development | No-op — contains only commented-out Visual Studio transform examples |
| `Web.Release.config` | `Release` | Both Internal and External | `<compilation xdt:Transform="RemoveAttributes(debug)" />` — removes only the `debug` attribute; no other difference between the two deployment variants |

## Environment variance

| Setting | DEV | TEST | PROD | Notes |
| --- | --- | --- | --- | --- |
| `aduserservices.allowedips` | Single IP address per non-production track (e.g. `entdev6`, `entdev7`, `enttest6`, `enttest7`, `np14`, `np18`, `np19`, `np20`, `np30`, `np31`, `npuat`, `preprod` — 12 tracks, one address each) | Same as DEV — single address per track | 4 addresses | `environmentsettings\settings.yml`; manifest name "Allowed IPs that can access the ADUserService", setting group `AdUserServices`, key `allowedips`, `secureFlag: false`, 13 deployment tracks total. Actual IP values are not reproduced here |

Variance is per deployment track (13 tracks in the manifest), not per build variant — neither `Web.Debug.config` nor `Web.Release.config` transforms any setting value; the only active transform removes the `debug` attribute. The hard-coded domain/container constants (`DOMAIN_EXT`, `DOMAIN_INT`, `CONTAINER_EXT`, `CONTAINER_INT`) do not vary by environment at all — every track points at the same two domains; see [Embedded constants](#embedded-constants).

## Logging configuration

| Aspect | Finding |
| --- | --- |
| Logging surface | None found — no `log4net` initialization or call, no `Trace.WriteLine`, no `EventLog` write, no `StreamWriter` exists anywhere in source, despite the `log4net 2.0.5` package reference |
| Destination | Not determined from source — no destination is configured because no logging call exists |
| File naming | — |
| Enabled by | Not applicable — no logging surface exists |
| Configured in | — |

## Related documentation
- [Service index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Activation and hosting](activation-hosting.md)
- [Operations](operations.md)
- [Faults and error pipeline](faults.md)
- [Authentication and authorization](authentication-authorization.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Operational runbook](operational-runbook.md)
- [Tech debt](tech-debt.md)

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Sources
- `src\ADUserServices\Web.config`
- `src\ADUserServices\Web.Debug.config`
- `src\ADUserServices\Web.Release.config`
- `src\ADUserServices\clsADUserServices.asmx.vb`
- `environmentsettings\settings.yml`
- `.saifdocgen\state\runs\20260922-101326-aduserservices\analysis\aduserservices-config-analysis.md`
